<?php namespace App\Http\Services;

use App\Images;
use File;
use Intervention\Image\Facades\Image;
use Storage;
use App\Files;
use Carbon\Carbon;
use App\Files as FileModel;

class FileManager
{
    /**
     * 上传文件分装方法
     * @param $filePath
     * @param $fileName
     * @return Files|mixed|static
     */
    public static function UploadFile($filePath,$fileName)
    {
        $fileMd5 = md5_file($filePath);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;
        if(!Storage::disk()->exists($toDirPath)){
            Storage::disk()->makeDirectory($toDirPath);
        }

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,File::get($filePath));
        }
        File::delete($filePath);
        $fileSize = Storage::disk()->size($toFilePath);
        $fileType = File::extension($fileName);
        $mimeType = Storage::disk()->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = ".".$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->save();
        }
        return $files;
    }

    public static function UploadBase64($baseContent = null){
        if($baseContent == null || $baseContent == '')
            throw new NotSupportedException(NotSupportedException::Base64NotNull);

        $fileMd5 = md5($baseContent);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;
        if(!Storage::disk()->exists($toDirPath)){
            Storage::disk()->makeDirectory($toDirPath);
        }

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$baseContent);
        }
        $fileName = time().'.jpg';
        $fileSize = Storage::disk()->size($toFilePath);
        $fileType = File::extension($fileName);
        $mimeType = Storage::disk()->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = ".".$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->save();
        }
        return $files;
    }

    public static function buildImageMultipx(FileModel $file){
        $fileContent = $file->getContent();

        $imageModel = Images::whereFileId($file->id)->first();

        if(!$imageModel){
            $image = Image::make($fileContent);

            $image1000px = Image::make($fileContent)->widen(1000)->encode($file->file_ext);
            $file1000px = FileManager::saveFileByFileContent($image1000px->encoded, $file->file_name . '-1000px.' . $file->file_type, $image1000px->mime());

            $image300px = Image::make($fileContent)->widen(300)->encode($file->file_ext);
            $file300px = FileManager::saveFileByFileContent($image300px->encoded, $file->file_name . '-300px.' . $file->file_type, $image300px->mime());

            $image100px = Image::make($fileContent)->widen(100)->encode($file->mime);
            $file100px = FileManager::saveFileByFileContent($image100px->encoded, $file->file_name . '-100px.' . $file->file_type, $image100px->mime());

            $imageModel = new Images();
            $imageModel->files()->associate($file);
            $imageModel->img_type = $file->file_type;
            $imageModel->img_name = $file->file_name;
            $imageModel->file300px()->associate($file300px);
            $imageModel->file100px()->associate($file100px);
            $imageModel->file1000px()->associate($file1000px);
            $imageModel->save();
        }

        return $imageModel;
    }

    public static function saveFileByFileContent($fileContent,$fileName,$mine){

        $fileMd5 = md5($fileContent);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;

        $fm = new FileManager();

        Storage::disk()->makeDirectory($toDirPath);
        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$fileContent);
        }

        $fileSize = Storage::disk()->size($toFilePath);
        $fileType = File::extension($fileName);
        $mimeType = Storage::disk()->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = ".".$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->save();
        }

        return $files;
    }

    public static function saveFileByWechatImg($filePath){
        $client   = new \GuzzleHttp\Client();
        $response = $client->get($filePath);
        $content  = $response->getBody()->getContents();
        $fileSize = $response->getHeader('Size');
        $mimeType = $response->getHeader('Content-Type');
        $filename = sprintf('%s_%s', 'weixin', $response->getHeader('chid')[0]);

        $fileMd5 = md5($content);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$content);
        }

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $filename;
            $files->file_url  = $toDirPath;
            $files->file_type = ".jpg";
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize[0];
            $files->file_ext  = $mimeType[0];
            $files->save();
        }
        return $files;
    }

    public static function saveFileByWechatHeaderImg($filePath,$fileName){
        $client   = new \GuzzleHttp\Client();
        $response = $client->get($filePath);
        $content  = $response->getBody()->getContents();
        $fileSize = $response->getHeader('Content-Length');
        $mimeType = $response->getHeader('Content-Type');

        $fileMd5 = md5($content);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$content);
        }

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize[0])->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = ".jpg";
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize[0];
            $files->file_ext  = $mimeType[0];
            $files->save();
        }
        return $files;
    }

    public static function saveFileByQrcodeImg($filePath){
        $client   = new \GuzzleHttp\Client();
        $response = $client->get($filePath);
        $content  = $response->getBody()->getContents();
        $fileSize = $response->getHeader('Content-Length');
        $mimeType = $response->getHeader('Content-Type');
        $filename = 'qrcode'. mt_rand(100000, 999999);

        $fileMd5 = md5($content);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$content);
        }

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize[0])->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $filename;
            $files->file_url  = $toDirPath;
            $files->file_type = ".jpg";
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize[0];
            $files->file_ext  = $mimeType[0];
            $files->save();
        }
        return $files;
    }

    /**
     * 删除文件封装方法
     * @param $id
     * @return bool
     * @throws \Exception
     */
    public static function deleteFile($id){
        /** @var Files $file */
        $file = Files::find($id);

        $path = $file->file_url . '/' . $file->file_md5;

        if(Storage::disk()->exists($path)){
            Storage::disk()->delete($path);
            $file->delete();
            return true;
        }
        return false;
    }

    public static function uploadCropFile($filePath,$content,$filename,$type){

        $fileMd5 = md5_file($filePath);
        $now = Carbon::now();

        $toDirPath = $now->year.'/'.$now->month.'/'.$now->day;
        $toFilePath = $toDirPath.'/'.$fileMd5;

        if(!Storage::disk()->exists($toDirPath)){
            Storage::disk()->makeDirectory($toDirPath);
        }

        if(!Storage::disk()->exists($toFilePath)){
            Storage::disk()->put($toFilePath,$content);
            unlink($filePath);
        }
        $fileSize = Storage::disk()->size($toFilePath);
        $fileType = $type;
        $mimeType = Storage::disk()->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();

        if(!$files){
            $files = new Files();
            $files->file_name = $filename;
            $files->file_url  = $toDirPath;
            $files->file_type = ".".$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->save();
        }

        return $files;
    }
}